package com.itheima.d1_polymorphism;

import com.sun.security.jgss.GSSUtil;

public class Demo02 {
    public static void main(String[] args) {
        // 目标：掌握使用多态的好处，以及多态下的类型转换问题。

        //父类型可以接收子类对象
        //多态好处
        People p = new Teacher();
        //Student[] students = new Student[3];
        //students[0] = new Student();
        //students[1] = new Teacher();//报错，学生数组不能存放老师对象
        //设计一个数组，数组即可以存放学生对象，也可以存放老师对象
        Object[] people = new People[3];
        people[0] = new Student();
        people[1] = new Teacher();

        //设计方法的时候，参数可以使用父类型。调用方法时传参就方便了，实参可以是该父类型及其子类型
        show(new Student());
        //show(new Teacher());


        //多态弊端
        //多态中，父类型变量，不能调用子类型中特有成员

        People p1 = new Teacher();//类型向上转型，对象的真实类型还是Teacher
        People p2 = new Student();
        //调用Teacher的teach方法
        //调用Student的study
//        p1.teach();
//        p2.study();

        //多态弊端的解决
        //如果想要访问子类型的特有成员，必须要将父类型强转为子类型
        Teacher t1 = (Teacher) p1;
        t1.teach();

        Student s1 = (Student) p2;
        s1.study();


        People p3 = new Teacher();
        Teacher t3 = (Teacher) p3;
        //Student s3 = (Student) p3; //报错，类型转换异常
        //报错。p3对象的真实类型是Teacher，不能转为Student。Student不是Teacher的父类型，不能用来表示Teacher类型

        System.out.println("=========");
        show(new Teacher());
        show(new Student());

    }

    public static void show(People p) {
        //当进行向下转型的时候，要去考虑转型是否为失败。可以先进行类型的判断
        // 使用instanceof关键字来判断对象是否可以使用某个类型来表示。如果可以就放心强转
        if (p instanceof Student) {
            Student s = (Student) p;
            s.study();
        }

        if (p instanceof Teacher) {
            Teacher t = (Teacher) p;
            t.teach();
            t.run();
        }

    }

}
